package com.xx.permission.utils;

import com.xx.permission.entity.result.DataPermission;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.PlainSelect;

import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author aqi
 * @since 2023/5/17 10:16
 * @describe JSqlParser工具类,用于通过API的方式操作SQL语句
 */
public class ExpressionUtils {

    private final static String LONG_TYPE = "long";
    private final static String STRING_TYPE = "string";

    /**
     * 构建in sql
     * @param tableName 表名
     * @param permission 字段权限
     * @return InExpression
     */
    public static InExpression buildInSql(String tableName, DataPermission permission) {
        // 把集合转变为JSQLParser需要的元素列表
        ItemsList itemsList = ExpressionUtils.handleFieldType(permission);
        // 创建IN表达式对象，传入列名及IN范围列表
        return new InExpression(new Column(tableName + "." + permission.getField()), itemsList);
    }

    /**
     * 构建查询语句之前,判断字段类型
     * @param permission 字段权限
     */
    private static ItemsList handleFieldType(DataPermission permission) {
        String fieldType = permission.getFieldType();
        if (Objects.equals(fieldType, LONG_TYPE)) {
            return new ExpressionList(permission.getValue().stream().map(LongValue::new).collect(Collectors.toList()));
        } else {
            return new ExpressionList(permission.getValue().stream().map(StringValue::new).collect(Collectors.toList()));
        }
    }

    /**
     * 构建eq sql
     * @param columnName 字段名称
     * @param value 字段值
     * @return EqualsTo
     */
    public static EqualsTo buildEq(String columnName, String value) {
       return new EqualsTo(new Column(columnName), new StringValue(value));
    }

    /**
     * 获取表名/别名
     * @param plainSelect plainSelect
     * @return 表名/别名
     */
    public static String getTableName(PlainSelect plainSelect) {
        // 获取别名
        Table table= (Table) plainSelect.getFromItem();
        Alias alias = table.getAlias();
        return null == alias ? table.getName() : alias.getName();
    }

    /**
     * 将2个where条件拼接到一起
     * @param plainSelect plainSelect
     * @param appendExpression 待拼接条件
     */
    public static void appendExpression(PlainSelect plainSelect, Expression appendExpression) {
        Expression where = plainSelect.getWhere() == null ? appendExpression : new AndExpression(plainSelect.getWhere(), appendExpression);
        plainSelect.setWhere(where);
    }
}
